/*
 * @lc app=leetcode.cn id=72 lang=typescript
 *
 * [72] 编辑距离
 *
 * https://leetcode.cn/problems/edit-distance/description/
 *
 * algorithms
 * Medium (62.90%)
 * Likes:    3411
 * Dislikes: 0
 * Total Accepted:    499.5K
 * Total Submissions: 794.2K
 * Testcase Example:  '"horse"\n"ros"'
 *
 * 给你两个单词 word1 和 word2， 请返回将 word1 转换成 word2 所使用的最少操作数  。
 *
 * 你可以对一个单词进行如下三种操作：
 *
 *
 * 插入一个字符
 * 删除一个字符
 * 替换一个字符
 *
 *
 *
 *
 * 示例 1：
 *
 *
 * 输入：word1 = "horse", word2 = "ros"
 * 输出：3
 * 解释：
 * horse -> rorse (将 'h' 替换为 'r')
 * rorse -> rose (删除 'r')
 * rose -> ros (删除 'e')
 *
 *
 * 示例 2：
 *
 *
 * 输入：word1 = "intention", word2 = "execution"
 * 输出：5
 * 解释：
 * intention -> inention (删除 't')
 * inention -> enention (将 'i' 替换为 'e')
 * enention -> exention (将 'n' 替换为 'x')
 * exention -> exection (将 'n' 替换为 'c')
 * exection -> execution (插入 'u')
 *
 *
 *
 *
 * 提示：
 *
 *
 * 0 <= word1.length, word2.length <= 500
 * word1 和 word2 由小写英文字母组成
 *
 *
 */

// @lc code=start
function minDistance(word1: string, word2: string): number {
  const memo = new Map<string, number>();

  function dp(i, j) {
    if (i < 0) {
      return j + 1;
    }

    if (j < 0) {
      return i + 1;
    }

    //查备忘录，避免重叠子问题
    if (memo.get(i + "-" + j) != undefined) {
      return memo.get(i + "-" + j);
    }

    if (word1[i] === word2[j]) {
      memo.set(i + "-" + j, dp(i - 1, j - 1));
    } else {
      memo.set(
        i + "-" + j,
        Math.min(dp(i - 1, j), dp(i, j - 1), dp(i - 1, j - 1)) + 1
      );
    }

    return memo.get(i + "-" + j)!;
  }

  return dp(word1.length - 1, word2.length - 1);
}
// @lc code=end
